package com.youlu.campus.admin.zm.service;

import com.google.common.collect.Lists;
import com.kuaidi100.sdk.response.QueryTrackData;
import com.kuaidi100.sdk.response.QueryTrackResp;
import com.youlu.campus.admin.zm.dto.SubOrderInfoDTO;
import com.youlu.campus.admin.zm.entity.SimpleOrderInfo;
import com.youlu.campus.admin.zm.entity.SimpleSubOrderInfo;
import com.youlu.campus.admin.zm.enums.RefundClickEnum;
import com.youlu.campus.admin.zm.msg.ZmResponse;
import com.youlu.campus.admin.zm.req.ZmReceiveMsgRequest;
import com.youlu.campus.admin.zm.task.DelayTask;
import com.youlu.campus.admin.zm.task.RedisDelayQueue;
import com.youlu.campus.base.sys.DelayMsgGray;
import com.youlu.campus.service.utils.ZmDateUtils;
import com.youlu.campus.admin.zm.utils.ZmMenuUtils;
import com.youlu.campus.admin.zm.utils.ZmUtils;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.OOrderInfo;
import com.youlu.campus.entity.OrderInfo;
import com.youlu.campus.entity.VO.req.OrderRefundOptVO;
import com.youlu.campus.service.course.CalLeaveDayService;
import com.youlu.campus.service.notify.KuaiDi100Service;
import com.youlu.campus.service.order.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import java.time.*;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author : [dengbo]
 * @className : ZmService
 * @description : [芝麻客服逻辑处理服务]
 * @createTime : [2022/11/9 17:50]
 */
@Service
@Slf4j
public class ZmApiService {

    private final static int DELIVERY_HOUR = 12;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private OrderService orderService;

    @Autowired
    private RedisDelayQueue redisDelayQueue;

    @Autowired
    private AsyncZmService asyncZmService;

    @Autowired
    private CalLeaveDayService calLeaveDayService;

    @Autowired
    private KuaiDi100Service kuaiDi100Service;

    public Object query(@RequestBody ZmReceiveMsgRequest req) throws Exception {
        log.info("order query request parma:{}", req);
        String content = req.getMessage().getContent();
        boolean isOrderNo = Pattern.matches("^2(\\d{11,24})(\\s*)[＋|+｜➕](\\s*)1[3-9]\\d{9}$", content);
        if (!isOrderNo) {
            // 没有输入正确订单号之前，输入订单号错误提示
            return ZmResponse.success(ZmMenuUtils.getErrorOrderNoAndPhoneQueryMsg());
        }
        String[] contents = content.split("[+|＋|➕]");
        String orderNo = contents[0].replaceAll("\\s*|\t|\r|\n", "");
        String phone = contents[1].replaceAll("\\s*|\t|\r|\n", "");
        SimpleOrderInfo orderInfo = asyncZmService.getSimpleOrderInfo(orderNo);
        if (orderInfo == null) {
            asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getQueryOrderNotExistMsg());
            return ZmResponse.success(ZmMenuUtils.getQueryFlowEndWithTransferMsg());
        }
        if (orderInfo.getMobile() == null || !orderInfo.getMobile().equals(phone)) {
            asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getQueryOrderPhoneNotEqInputPhoneMsg());
            return ZmResponse.success(ZmMenuUtils.getQueryFlowEndWithTransferMsg());
        }
        String userName = orderInfo.getName();
        // 相同订单第二次进来 同步发送
        String orderStatus = orderInfo.getStatus();
        log.info("user openid:{} order status:{}", req.getOpenid(), orderStatus);
        // 未支付
        if ("0".equals(orderStatus)) {
            asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getNotPayEndMsg(userName));
            return ZmResponse.success(ZmMenuUtils.getQueryFlowEndMsg());
        }
        // 订单退款
        if (Lists.newArrayList("6", "9").contains(orderStatus)) {
            asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getAlreadyRefundMsg(orderInfo.getRefundStatus(), userName));
            return ZmResponse.success(ZmMenuUtils.getQueryFlowEndMsg());
        }
        // 已经发货
        if ("4".equals(orderStatus)) {
            List<SimpleSubOrderInfo> subOrderInfos = asyncZmService.getSimpleSubOrderInfo(orderNo);
            if (CollectionUtils.isEmpty(subOrderInfos)) {
                asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getSubOrderNotExistMsg());
                return ZmResponse.success(ZmMenuUtils.getQueryFlowEndMsg());
            }
            // 按照日期排序
            subOrderInfos = subOrderInfos.stream().sorted(Comparator.comparing(SimpleSubOrderInfo::getUpdatedTime)).collect(Collectors.toList());
            boolean hasLogic = false;
            SimpleSubOrderInfo oldSubOrder = null;
            Set<String> logisticsNoList = new HashSet<>();
            Set<String> logisticsCompanyList = new HashSet<>();
            String address = "";
            String currentLogisticsNo = null;
            String currentLogisticsCompany = null;
            for (SimpleSubOrderInfo subOrderInfo : subOrderInfos) {
                // 补发
                if ("1".equals(subOrderInfo.getPostSaleStatus())) {
                    currentLogisticsNo = subOrderInfo.getPostSaleLogisticsNo();
                    if (StringUtils.isBlank(currentLogisticsNo)) {
                        continue;
                    }
                    currentLogisticsCompany = subOrderInfo.getPostSaleLogisticsCompany();
                    logisticsNoList.add(currentLogisticsNo);
                    logisticsCompanyList.add(currentLogisticsCompany);
                } else {
                    currentLogisticsNo = subOrderInfo.getLogisticsNo();
                    if (StringUtils.isBlank(currentLogisticsNo)) {
                        continue;
                    }
                    currentLogisticsCompany = subOrderInfo.getLogisticsCompany();
                    logisticsNoList.add(currentLogisticsNo);
                    logisticsCompanyList.add(currentLogisticsCompany);
                }
                if (oldSubOrder == null) {
                    oldSubOrder = subOrderInfo;
                }
                if (!hasLogic) {
                    try {
                        QueryTrackResp resp = kuaiDi100Service.queryTrackByLogisticsNo(currentLogisticsNo, currentLogisticsCompany, phone);
                        if (resp != null) {
                            Optional<QueryTrackData> newDeliverInfo = resp.getData().stream().findFirst();
                            if (newDeliverInfo.isPresent()) {
                                address = newDeliverInfo.get().getContext();
                                hasLogic = true;
                            }
                        }
                    } catch (Exception e) {
                        log.error("查询物流信息异常:{}", e.getMessage());
                    }
                }
            }
            if (hasLogic) {
                String logisticsNos = logisticsNoList.stream().filter(item -> StringUtils.isNotBlank(item)).collect(Collectors.joining(","));
                String logisticsCompanys = logisticsCompanyList.stream().filter(item -> StringUtils.isNotBlank(item)).collect(Collectors.joining(","));
                // 有物流信息并且更新了
                asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getDeliveryLogicUpdateMsg(userName, logisticsCompanys, logisticsNos, address));
                return ZmResponse.success(ZmMenuUtils.getQueryFlowEndMsg());
            }
            // 如果发货了，最早发货的子订单是否存在，不存在应该属于异常行为，转人工
            if (oldSubOrder == null) {
                asyncZmService.sendManualServiceFlow(req.getOpenid(), req.getFlowId(), false, false);
                return null;
            }
            Date updatedTime = oldSubOrder.getUpdatedTime();
            log.info("user openid:{} old sub order:{},delivery time:{}", req.getOpenid(), oldSubOrder, updatedTime);
            Date deliveryTime = ZmDateUtils.getZeroDate(updatedTime);
            Date nowTime = ZmDateUtils.getZeroDate(new Date());
            long num = ZmDateUtils.getTwoDateDiffDay(deliveryTime, nowTime);
            // 3天内发货，没有物流信息更新,
            if (num <= 3) {
                asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getDeliveryLess3DayNotLogicMsg(userName));
                return ZmResponse.success(ZmMenuUtils.getQueryFlowEndMsg());
            }
            // 超过3天转人工
            asyncZmService.sendManualServiceFlow(req.getOpenid(), req.getFlowId(), false, false);
            return null;
        }
        return queryNotDeliveryResult(orderNo, req.getOpenid(), req.getFlowId(), userName, orderInfo.getPayTime());
    }

    /**
     * 处理查询未发货信息
     *
     * @param orderNo
     * @param openId
     * @param flowId
     * @param userName
     * @param payTime
     * @return
     */
    public Object queryNotDeliveryResult(String orderNo, String openId, Long flowId, String userName, Date payTime) {
        // 获取工作日天数
        int num = calLeaveDayService.getCalLeaveDaysNum(payTime,new Date());
        log.info("openid:{},orderNo={} not delivery day={}", openId, orderNo, num);
        // 算当天
        if (num <= 0) {
            asyncZmService.sendOneMsg(openId, flowId, ZmMenuUtils.getCurrentDayNotDeliveryMsg(userName));
            return ZmResponse.success(ZmMenuUtils.getQueryFlowEndMsg());
        }
        if (num > 9) {
            asyncZmService.sendManualServiceFlow(openId, flowId, false, false);
            return null;
        }
        asyncZmService.sendOneMsg(openId, flowId, ZmMenuUtils.getWorkDayNotDeliveryLess9Msg(userName, num));
        return ZmResponse.success(ZmMenuUtils.getQueryFlowEndMsg());
    }

    /**
     * 接收处理芝麻客服消息
     *
     * @param req
     * @return
     * @throws Exception
     */
    public Object zmReceive(@RequestBody ZmReceiveMsgRequest req) {
        if (StringUtils.isBlank(req.getOpenid()) || req.getFlowId() == null) {
            log.error("openid is empty or flow id is null");
            return null;
        }
        DelayMsgGray delayMsgGray = asyncZmService.getDelayMsgGray();
        if (delayMsgGray.getOpenReplayTime()) {
            LocalDateTime time = LocalDateTime.now();
            LocalDate date = time.toLocalDate();
            LocalDateTime start = LocalDateTime.of(date, LocalTime.of(delayMsgGray.getStartHour(), delayMsgGray.getStartMin()));
            LocalDateTime end = LocalDateTime.of(date, LocalTime.of(delayMsgGray.getEndHour(), delayMsgGray.getEndMin()));

            if (time.isBefore(start) || time.isAfter(end)) {
                asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getNotServerTimeMsg());
                asyncZmService.sendEndFlow(req.getOpenid(), req.getFlowId());
                return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
            }
        }
        Integer menuId = req.getMessage().getMsgMenuId();
        String content = req.getMessage().getContent();
        // 是否是单击自定义按钮进入
        if (menuId != null && menuId > 0) {
            Map<String, String> cacheResult = asyncZmService.getFlowCache(req.getOpenid(), req.getFlowId());
            if (MapUtils.isEmpty(cacheResult)) {
                // 结束流程
                if (menuId == RefundClickEnum.END_FLOW.getId()) {
                    // 自动结束流程
                    asyncZmService.sendEndFlow(req.getOpenid(), req.getFlowId());
                    return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
                }
                // 被强制开启新一轮会话时，如果未输入正确订单号之前，点击上一轮不回复任何消息
                return null;
            }
            boolean isDelayMsg = isSendDelayMsg(delayMsgGray, req.getOpenid());
            // 第一条消息没有发送完成，不回复
            if (firstMsgIsNotEnd(isDelayMsg, cacheResult.get("firstMsgEnd"))) {
                return null;
            }
            // (发货退款  || 12小时之后未发货退款)
            if (menuId == RefundClickEnum.DELIVERY_CONFIRM.getId() || menuId == RefundClickEnum.NOT_DELIVERY_MORE12_CONFIRM.getId()) {
                log.info("openId {} flowId:{} manual server deal", req.getOpenid(), req.getFlowId());
                // 转人工并且结束流程，【这个时候证书在制作中或者发货了】
                asyncZmService.sendManualServiceFlow(req.getOpenid(), req.getFlowId(), true, true);
                return null;
            }
            String orderNo = cacheResult.get("orderNo");
            OrderInfo orderInfo = mongoTemplate.findOne(new Query(Criteria.where("orderNo").is(orderNo)), OrderInfo.class);
            if (orderInfo == null) {
                return ZmResponse.success(ZmMenuUtils.getRefundOrderNotExistMsg());
            }
            String userName = StringUtils.isBlank(orderInfo.getName()) ? "" : orderInfo.getName();
            Integer itemType = Integer.valueOf(cacheResult.get("itemType"));
            // 发货不退款
            if (menuId == RefundClickEnum.DELIVERY_CANCEL.getId()) {
                String logisticsCompanys = cacheResult.get("logisticsCompanys");
                String logNos = cacheResult.get("logisticsNos");
                //发送回复消息 结束流程，清除缓存
                asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getDeliveryNotRefundClickMsg(userName, logisticsCompanys, logNos), true, true);
                return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
            }
            // 12小时之内未发货退款
            if (menuId == RefundClickEnum.NOT_DELIVERY_LESS12_CONFIRM.getId()) {
                return ZmResponse.success(ZmMenuUtils.getNotDeliveryLess12RefundClickMsg(userName, itemType));
            }
            // 未发货不退款 ( 12小时之内 ||  12小时以后）||  (12小时之内未发货退款 取消)
            if (menuId == RefundClickEnum.NOT_DELIVERY_LESS12_CANCEL.getId() || menuId == RefundClickEnum.NOT_DELIVERY_MORE12_CANCEL.getId()
                    || menuId == RefundClickEnum.NOT_DELIVERY_REFUND_CANCEL.getId()) {
                asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getNotRefundClickMsg(itemType), true, true);
                return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
            }
            // 12小时之内未发货退款 确定
            if (menuId == RefundClickEnum.NOT_DELIVERY_REFUND_CONFIRM.getId()) {
                return getNotDeliveryRefundConfirmClickResponse(orderInfo, req.getOpenid(), req.getFlowId(), userName);
            }
            // 转人工
            if (menuId == RefundClickEnum.TRANSFER.getId()) {
                asyncZmService.sendManualServiceFlow(req.getOpenid(), req.getFlowId(), true, true);
                return null;
            }
            // 结束流程
            if (menuId == RefundClickEnum.END_FLOW.getId()) {
                // 结束流程，清除缓存
                asyncZmService.sendEndFlow(req.getOpenid(), req.getFlowId(), true);
                return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
            }
            return null;
        }
        boolean isOrderNoAndPhone = Pattern.matches("^2(\\d{11,24})(\\s*)[＋|+｜➕](\\s*)1[3-9]\\d{9}$", content);
        if (!isOrderNoAndPhone) {
            Map<String, String> cacheResult = asyncZmService.getFlowCache(req.getOpenid(), req.getFlowId());
            // 输入非订单号第一次进入
            boolean isFirst = MapUtils.isEmpty(cacheResult);
            if (isFirst) {
                // 人工处理
                if (content != null && content.contains("人工")) {
                    asyncZmService.sendManualServiceFlow(req.getOpenid(), req.getFlowId(), true, false);
                    return null;
                }
                // 结束流程
                if ("结束流程".equals(content) || "结束".equals(content)) {
                    // 自动结束流程
                    asyncZmService.sendEndFlow(req.getOpenid(), req.getFlowId());
                    return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
                }
                // 连续输入3次错误结束流程
                if (isInputErrorMore3ToTranster(req.getOpenid(), req.getFlowId(), delayMsgGray.getInputErrorTime())) {
                    return null;
                }
                // 没有输入正确订单号之前，输入订单号错误提示
                return ZmResponse.success(ZmMenuUtils.getErrorOrderNoAndPhoneRefundMsg());
            }
            if ("结束流程".equals(content) || "结束".equals(content)) {
                // 结束流程，清除缓存
                asyncZmService.sendEndFlow(req.getOpenid(), req.getFlowId(), true);
                return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
            }
            // 输入正确订单号进入流程，输入错误订单号/获取其他信息 回复第一次发送订单号的文案
            boolean isDelayMsg = isSendDelayMsg(delayMsgGray, req.getOpenid());
            // 第一条消息是否发送结束了
            if (firstMsgIsNotEnd(isDelayMsg, cacheResult.get("firstMsgEnd"))) {
                return null;
            }
            // 获取商品类型
            String orderNo = cacheResult.get("orderNo");
            SimpleOrderInfo orderInfo = asyncZmService.getSimpleOrderInfo(orderNo);
            if (orderInfo == null) {
                return ZmResponse.success(ZmMenuUtils.getRefundOrderNotExistMsg());
            }
            SubOrderInfoDTO dto = buildOrderDto(cacheResult, orderInfo);
            return sendSyncMsg(req, dto);
        }
        String[] contents = content.split("[+|＋|➕]");
        String orderNo = contents[0].replaceAll("\\s*|\t|\r|\n", "");
        String phone = contents[1].replaceAll("\\s*|\t|\r|\n", "");
        log.info("openid:{} user intput str convert,orderNo={},phone={}", req.getOpenid(), orderNo, phone);
        boolean isDelayMsg = isSendDelayMsg(delayMsgGray, req.getOpenid());
        Map<String, String> cacheResult = asyncZmService.getFlowCache(req.getOpenid(), req.getFlowId());
        boolean isFirst = MapUtils.isEmpty(cacheResult);
        if (isFirst) {
            SimpleOrderInfo orderInfo = asyncZmService.getSimpleOrderInfo(orderNo);
            // 之前缓存了订单查询，后面又改成了实时查询订单了
            if (orderInfo == null) {
                // 连续输入3次错误结束流程
                if (isInputErrorMore3ToTranster(req.getOpenid(), req.getFlowId(), delayMsgGray.getInputErrorTime())) {
                    return null;
                }
                return ZmResponse.success(ZmMenuUtils.getRefundOrderNotExistMsg());
            }
            if (orderInfo.getMobile() == null || !orderInfo.getMobile().equals(phone)) {
                // 连续输入3次错误结束流程
                if (isInputErrorMore3ToTranster(req.getOpenid(), req.getFlowId(), delayMsgGray.getInputErrorTime())) {
                    return null;
                }
                return ZmResponse.success(ZmMenuUtils.getOrderPhoneNotEqInputPhoneMsg());
            }
            // 设置缓存消息
            cacheResult = asyncZmService.setFlowCache(req, orderNo, phone, isDelayMsg);
            if (isDelayMsg) {
                // 延时发送
                String taskId = ZmUtils.makeTaskId(req.getOpenid(), req.getFlowId());
                DelayTask delayTask = new DelayTask();
                delayTask.setTaskId(taskId);
                delayTask.setMsg("");
                redisDelayQueue.addRandomDelayTask(delayTask);
                return ZmResponse.success(ZmMenuUtils.getUserFirstInMsg());
            }
            SubOrderInfoDTO dto = buildOrderDto(cacheResult, orderInfo);
            return sendSyncMsg(req, dto);
        }
        // 同一个流程 第二次进入 输入其他订单号
        String cacheOrderNo = cacheResult.get("orderNo");
        if (!cacheOrderNo.equals(orderNo)) {
            return ZmResponse.success(ZmMenuUtils.getEndFlowMenuMsg(cacheOrderNo));
        }
        //延迟消息需要判断第一条消息是否发送完成, 第一条消息没有发送完成，不回复
        if (firstMsgIsNotEnd(isDelayMsg, cacheResult.get("firstMsgEnd"))) {
            return null;
        }
        if ("结束流程".equals(content) || "结束".equals(content)) {
            // 结束流程，清除缓存
            asyncZmService.sendEndFlow(req.getOpenid(), req.getFlowId(), true);
            return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
        }
        // 之前缓存了订单查询，后面又改成了实时查询订单了
        SimpleOrderInfo orderInfo = asyncZmService.getSimpleOrderInfo(orderNo);
        if (orderInfo == null) {
            return ZmResponse.success(ZmMenuUtils.getRefundOrderNotExistMsg());
        }
        SubOrderInfoDTO dto = buildOrderDto(cacheResult, orderInfo);
        return sendSyncMsg(req, dto);
    }

    public boolean isInputErrorMore3ToTranster(String openId, Long flowId, Integer errorNum) {
        // 连续输入3次错误结束流程
        if (asyncZmService.inputErrorTimeMore3(openId, flowId, errorNum)) {
            // 转人工 结束流程
            asyncZmService.sendManualServiceFlow(openId, flowId, true, false);
            // 清除缓存次数
            asyncZmService.clearErrorTimeMore3(openId, flowId);
            return true;
        }
        return false;
    }

    public SubOrderInfoDTO buildOrderDto(Map<String, String> cacheResult, SimpleOrderInfo orderInfo) {
        SubOrderInfoDTO dto = new SubOrderInfoDTO();
        dto.setItemType(Integer.valueOf(cacheResult.get("itemType")));
        dto.setLogisticsNos(cacheResult.get("logisticsNos"));
        dto.setLogisticsCompanys(cacheResult.get("logisticsCompanys"));
        String userName = StringUtils.isBlank(orderInfo.getName()) ? "" : orderInfo.getName();
        dto.setUserName(userName);
        dto.setStatus(orderInfo.getStatus());
        dto.setRefundStatus(orderInfo.getRefundStatus());
        dto.setPayTime(orderInfo.getPayTime());
        return dto;
    }

    public ZmResponse sendSyncMsg(ZmReceiveMsgRequest req, SubOrderInfoDTO dto) {
        String userName = dto.getUserName();
        // 相同订单第二次进来 同步发送
        String orderStatus = dto.getStatus();
        log.info("user openid:{} order status:{}", req.getOpenid(), orderStatus);
        // 未支付
        if ("0".equals(orderStatus)) {
            asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getNotPayEndMsg(userName));
            // 结束流程，清除缓存
            asyncZmService.sendEndFlow(req.getOpenid(), req.getFlowId(), true);
            return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
        }
        // 订单退款
        if (Lists.newArrayList("6", "9").contains(orderStatus)) {
            asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getAlreadyRefundMsg(dto.getRefundStatus(), userName));
            // 结束流程，清除缓存
            asyncZmService.sendEndFlow(req.getOpenid(), req.getFlowId(), true);
            return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
        }
        // 已经发货
        if ("4".equals(orderStatus)) {
            asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getDeliveryNewMsg(dto.getItemType(), userName, dto.getLogisticsCompanys(), dto.getLogisticsNos()), true, true);
            return ZmResponse.success(ZmMenuUtils.getRefundFlowEndWithTransferMsg());
        }
        // 未发货
        Date payTime = dto.getPayTime();
        long hour = (System.currentTimeMillis() - payTime.getTime()) / 1000 / 3600;
        log.info("user openid:{} current time to pay time hour:{}", req.getOpenid(), hour);
        // 12小时之内
        if (hour < DELIVERY_HOUR) {
            return ZmResponse.success(ZmMenuUtils.getNotDeliveryLess12Msg(dto.getItemType(), userName));
        }
        // 12 小时之后
        asyncZmService.sendOneMsg(req.getOpenid(), req.getFlowId(), ZmMenuUtils.getNotDeliveryMore12NewResponse(dto.getItemType(), userName), true, true);
        return ZmResponse.success(ZmMenuUtils.getRefundFlowEndWithTransferMsg());
    }


    public boolean isSendDelayMsg(String openId) {
        DelayMsgGray delayMsgGray = asyncZmService.getDelayMsgGray();
        // 是否开启更新头像
        if (!delayMsgGray.getOpened()) {
            return false;
        }
        // 延时发送
        return delayMsgGray.getOpenIdList().stream().anyMatch(item -> "*".equals(item) || item.equals(openId));
    }

    public boolean isSendDelayMsg(DelayMsgGray delayMsgGray, String openId) {
        // 是否开启更新头像
        if (!delayMsgGray.getOpened()) {
            return false;
        }
        // 延时发送
        return delayMsgGray.getOpenIdList().stream().anyMatch(item -> "*".equals(item) || item.equals(openId));
    }

    public boolean firstMsgIsNotEnd(boolean isDelayMsg, String firstMsgEnd) {
        return isDelayMsg && "0".equals(firstMsgEnd);
    }

    public ZmResponse getNotDeliveryRefundConfirmClickResponse(OrderInfo orderInfo, String openid, Long flowId, String userName) {
        // 未支付
        if ("0".equals(orderInfo.getStatus())) {
            // 发送未支付消息 结束流程，清除缓存
            asyncZmService.sendOneMsg(openid, flowId, ZmMenuUtils.getNotPayEndMsg(userName), true, true);
            return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
        }
        // 订单退款
        if (Lists.newArrayList("6", "9").contains(orderInfo.getStatus())) {
            // 发送已经退款消息 结束流程，清除缓存
            asyncZmService.sendOneMsg(openid, flowId, ZmMenuUtils.getAlreadyRefundMsg("3", userName), true, true);
            return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
        }
        Date payTime = orderInfo.getPayTime();
        long hour = (System.currentTimeMillis() - payTime.getTime()) / 1000 / 3600;
        log.info("user openid:{} current time to pay time hour:{}", openid, hour);
        // 点击打款按钮，如果订单超过12小时转人工
        if (hour >= DELIVERY_HOUR) {
            // 转人工并且结束流程,清除缓存
            asyncZmService.sendManualServiceFlow(openid, flowId, true, true);
            return null;
        }
        //退款状态,0:未退款,1:退款申请,2:退款中,3:退款完成,4:待返货 7:部分退款中
        String orderNo = orderInfo.getOrderNo();
        Query querySubOrder = new Query();
        querySubOrder.addCriteria(Criteria.where("orderNo").is(orderNo));
        List<OOrderInfo> subOrders = mongoTemplate.find(querySubOrder, OOrderInfo.class);
        if (CollectionUtils.isEmpty(subOrders)) {
            log.error("openId:{} flowid orderNo:{} order sub order not exist", openid, flowId, orderNo);
            return ZmResponse.success(ZmMenuUtils.getSubOrderNotExistMsg());
        }
        OrderRefundOptVO req = new OrderRefundOptVO();
        req.setId(orderInfo.getId());
        req.setRefundWay("on-line");
        req.setOptName("芝麻客服机器人");
        req.setSourcePlatform("芝麻客服-接入平台");
        try {
            //退款
            orderService.doRefundPassVerify(req, orderInfo, subOrders);
            // 发送消息 结束流程，清除缓存
            asyncZmService.sendOneMsg(openid, flowId, ZmMenuUtils.getConfirmRefundClickMsg(), true, true);
            return ZmResponse.success(ZmMenuUtils.getFlowEndMsg());
        } catch (BusinessException e) {
            log.error("openId:{} flowId:{} zm refund Bu-error:{}", openid, flowId, e.getMessage());
            // 转人工并且结束流程
            asyncZmService.sendManualServiceFlow(openid, flowId, true, true);
            return null;
        } catch (Exception e) {
            log.error("openId:{} flowId:{} zm refund Ex-error", openid, flowId, e);
            // 转人工并且结束流程
            asyncZmService.sendManualServiceFlow(openid, flowId, true, true);
            return ZmResponse.success(ZmMenuUtils.setTextMsg("退款失败"));
        }
    }
}
